<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>

</body>
<script>
    // prototype原型对象（显式原型对象）
    // > 每个函数都有一个名为prototype的属性，该属性的类型为对象，该对象被称为原型对象（显式原型对象）。
    // {
    //     function fn(){
    //
    //     }
    //
    //     console.log(fn.prototype);
    //
    //     const obj = {
    //
    //     }
    //     console.log(obj.prototype)// undefined
    // }


    // ### constructor(构造器)
    // * 原型对象拥有constructor属性，该属性我们称其为构造器,它指向构造函数本身。
    // {
    //     function Box(){
    //
    //     }
    //
    //     console.log(Box.prototype.constructor === Box);// true
    //
    //     const obj = new Box();
    //     console.log(obj.__proto__.constructor === Box);// true
    //     console.log(obj.constructor === Box);// true
    //
    // }

    // * 给原型对象添加属性(一般都是方法)，函数的所有实例对象自动拥有原型中的属性(方法)
    // {
    //     function Box(){
    //         // this.userName = "zhangsan";
    //     }
    //     Box.prototype.userName = "lisi";
    //     const obj = new Box();
    //     const obj2 = new Box();
    //     obj2.userName = "wangwu";
    //     console.log(obj.userName,obj2.userName,obj2.__proto__.userName);// lisi wangwu lisi
    //
    // }


    // ### 1.3、`__proto__`（隐式原型对象）
    // - 每个实例对象都有一个`__proto__`，可称为隐式原型
    // {
    //     function Box(){
    //
    //     }
    //     // 将构造函数通过new进行实例化，将实例化的结果赋值给obj,obj可以称为构造函数Box的实例。
    //     const obj = new Box();
    //     console.log(obj.__proto__ === Box.prototype);
    // }
    // - 对象的隐式原型的值为其对应构造函数的显式原型的值


    // ### 1.4、原型链
    // - 所有的实例对象都有`__proto__`属性, 它指向的就是原型对象
    // {
    //     function Box(){
    //
    //     }
    //     const obj = new Box();
    //     const obj2 = new Box();
    //     console.log(obj.__proto__ === Box.prototype);// true
    //     console.log(obj2.__proto__ === Box.prototype);// true
    //     console.log(obj.__proto__ === obj2.__proto__);// true
    // }
    // - 这样通过`__proto__`属性就形成了一个链的结构---->原型链
    // {
    //     function Box(){
    //
    //     }
    //     const obj = new Box();
    //     console.log(obj.__proto__ === Box.prototype);// true
    //     console.log(Box.prototype.__proto__ === Object.prototype);// true
    //     console.log(Object.prototype.__proto__);// null
    //     console.log(obj.__proto__.__proto__.__proto__);// null
    // }
    // - 当查找对象内部的属性/方法时,` js`引擎自动沿着这个原型链查找
    // {
    //     function Box(){
    //         // this.userName = "zhangsan";
    //     }
    //     // Box.prototype.userName = "lisi";
    //     // Object.prototype.userName = "wangwu";
    //     const obj = new Box();
    //     console.log(obj.__proto__ === Box.prototype);// true
    //     console.log(Box.prototype.__proto__ === Object.prototype);// true
    //     console.log(Object.prototype.__proto__);// null
    //     console.log(obj.__proto__.__proto__.__proto__);// null
    //     console.log(obj.userName);
    // }

    // - 当给对象属性赋值时不会使用原型链, 而只是在当前对象中进行操作
    {
        function Box(){
            // this.userName = "zhangsan";
        }
        const obj = new Box();
        Box.prototype.userName = "lisi";
        console.log(obj.__proto__ === Box.prototype);// true
        console.log(Box.prototype.__proto__ === Object.prototype);// true
        console.log(Object.prototype.__proto__);// null
        console.log(obj.__proto__.__proto__.__proto__);// null
        obj.userName = "wangwu";
        console.log(obj);
    }
</script>
</html>